﻿using System;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Text;

namespace TM.DataAccessor
{
    public class DataAccessor : IDataAccessor, IDisposable
    {
        private IDbCommand _command;
        private IDbConnection _dbConnection;

        public DataAccessor(IDbCommand command, IDbConnection dbConnection)
        {
            //_dbConnection = new SQLiteConnection(ConfigurationManager.ConnectionStrings["SQLiteConnection"].ConnectionString);
            _dbConnection = dbConnection;
            _command = command;
            _command.Connection = _dbConnection;
        }

        #region Implementation of IDataAccessor

        public ConnectionState Open()
        {
            if(_dbConnection.State== ConnectionState.Closed)
            {
                _dbConnection.Open();
            }

            return _dbConnection.State;
        }

        public ConnectionState Close()
        {
            if (_dbConnection.State != ConnectionState.Closed)
            {
                _dbConnection.Close();
            }

            return _dbConnection.State;
        }

        public int ExecuteNonQuery()
        {
            if (_command == null) return 0;

            this.Open();

            var result = _command.ExecuteNonQuery();
            return result;
        }

        public DataTable ExecuteReader()
        {
            if (_command == null) return null;

            this.Open();

            var reader = _command.ExecuteReader();
            var dataTable = new DataTable();
            dataTable.Load(reader);
            return dataTable;
        }

        public DataTable ExecuteReader(string sqlScript)
        {
            if (_command == null) return null;

            _command.CommandType = CommandType.Text;
            _command.CommandText = sqlScript;

            this.Open();

            var reader = _command.ExecuteReader();
            var dataTable = new DataTable();
            dataTable.Load(reader);
            return dataTable;
        }

        public DataTable ExecuteReader(string sqlScript, object[] parameters)
        {
            if (_command == null) return null;

            _command.CommandType = CommandType.Text;
            _command.CommandText = string.Format(sqlScript, parameters);

            this.Open();

            var reader = _command.ExecuteReader();
            var dataTable = new DataTable();
            dataTable.Load(reader);
            return dataTable;
        }

        public IDbTransaction BeginTransaction(string transactionName = null)
        {
            if (_dbConnection.State!= ConnectionState.Open)
            {
                _dbConnection.Open();
            }

            return _dbConnection.BeginTransaction();
        }

        public void EndTransaction(IDbTransaction theTransaction, bool isSuccess)
        {
            if(isSuccess)
            {
                theTransaction.Commit();
            }
            else
            {
                theTransaction.Rollback();
            }

            this.Close();
        }

        public IDbCommand Command
        {
            get { return _command; }
            private set { _command = value; }
        }

        #endregion

        #region Implementation of IDisposable

        /// <summary>
        /// Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
        /// </summary>
        /// <filterpriority>2</filterpriority>
        public void Dispose()
        {
            if (_command != null) _command.Dispose();
            if (_dbConnection != null)
            {
                if (_dbConnection.State == ConnectionState.Open)
                    _dbConnection.Close();
                _dbConnection.Dispose();
            }
        }

        #endregion
    }
}
